> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.yYcpgRTA-$1/rev.13
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// http://forum.processing.org/topic/when-rects-intersect-randomize-fill-color-once
// http://forum.processing.org/topic/rect-line-intersection-problem
// http://studio.processingtogether.com/sp/pad/export/ro.9owuz0wKx1ph7/latest

final static color BG = 0250;

final static short MIN_SPD = 2, MAX_SPD = 5;
final static short POS = 60, OFF = POS >> 2;
final static short NUM = 15, DIM = POS >> 1;
final static short FPS = 50, BOLD = 2;

final RectPair[] rects = new RectPair[NUM];

void setup() {
  size(500, NUM * POS);
  frameRate(FPS);
  strokeWeight(BOLD);
  smooth();

  for (int i=0; i!=NUM; i++)
    rects[i] = new RectPair( random(DIM, width - POS), i*POS + OFF, 
    DIM, DIM, 0, i*POS + OFF, DIM, DIM, random(MIN_SPD, MAX_SPD) );
}

void draw() {
  background(BG);

  for (RectPair r: rects)  r.script();
}

void mousePressed() {
  looping = !looping;
}

void keyPressed() {
  mousePressed();
}

/*
static final boolean checkIntersect(
 float left, float top, float right, float bottom, 
 float oLeft, float oTop, float oRight, float oBottom) {
 
 return left < oRight & right > oLeft 
 & top < oBottom & bottom > oTop;
 }
 */

final class RectPair {
  final short rX1, rY1, rW1, rH1;
  final short rXW;

  float rX2;
  final short rY2, rW2, rH2;

  float sp;

  boolean hasCollided;
  color c;

  static final color OFF = -1;

  RectPair(float _rX1, float _rY1, float _rW1, float _rH1, 
  float _rX2, float _rY2, float _rW2, float _rH2, float _spd) {

    rX1 = (short) _rX1;  // x
    rY1 = (short) _rY1;  // y
    rW1 = (short) _rW1;  // w
    rH1 = (short) _rH1;  // h

    rX2 = _rX2;          // x
    rY2 = (short) _rY2;  // y
    rW2 = (short) _rW2;  // w
    rH2 = (short) _rH2;  // h

    sp = _spd;   // movement speed.

    rXW = (short) (rX1 + rW1); // x + w
  } 

  void script() {
    bounce();
    pick();
    display();
  }

  void bounce() {
    if ( (rX2 += sp) < 0 | rX2 > width - rW2 )   sp *= -1;
  }

  void pick() {
    final boolean isColliding = checkTouch();

    /*
    final boolean isColliding = checkIntersect(
     rX1, rY1, rXW, rY1+rH1, rX2, rY2, rX2+rW2, rY2+rH2);
     */

    // checks whether state has changed & updates current state:
    if ( hasCollided != (hasCollided = isColliding) )
      // picks a new color if it has just collided:
      c = (color) random(#000000);
  }

  void display() {
    fill(hasCollided? c:OFF);

    rect(rX1, rY1, rW1, rH1);
    rect(rX2, rY2, rW2, rH2);
  }

  boolean checkTouch() {
    return rX1 < rX2 + rW2 & rXW > rX2;
  }
}